package drds.server.sqlparser.sqlobject.statement.query;

import java.util.ArrayList;
import java.util.List;

import drds.server.sqlparser.sqlobject.AbstractSqlObject;
import drds.server.sqlparser.sqlobject.expression.Expression;
import drds.server.sqlparser.sqlobject.statement.query.order_by.OrderBy;
import drds.server.sqlparser.sqlobject.statement.table.ITable;
import drds.server.sqlparser.visitor.Visitor;

/**
 * 查询
 * 
 * @author 曹正辉<330937205@qq.com>
 * 
 */
public class Query extends AbstractSqlObject implements IQuery {
	public final static String DISTINCT = "distinct";
	/**
	 * 量词
	 */
	protected String quantifier;
	protected final List<SelectItem> selectItemList = new ArrayList<SelectItem>();
	protected ITable from;
	protected Expression where;
	protected GroupBy groupBy;
	private OrderBy orderBy;
	private Limit limit;
	private boolean forUpdate = false;

	public Query() {

	}

	public void setQuantifier(String quantifier) {
		this.quantifier = quantifier;
	}

	public String getQuantifier() {
		return this.quantifier;
	}

	public void addSelectItem(SelectItem selectItem) {
		this.selectItemList.add(selectItem);
		selectItem.setParent(this);
	}

	public List<SelectItem> getSelectItemList() {
		return this.selectItemList;
	}

	public void setFrom(ITable from) {
		this.from = from;
	}

	public ITable getFrom() {
		return this.from;
	}

	public void setWhere(Expression where) {
		if (where != null) {
			where.setParent(this);
		}
		this.where = where;
	}

	public Expression getWhere() {
		return this.where;
	}

	public void setGroupBy(GroupBy groupBy) {
		this.groupBy = groupBy;
	}

	public GroupBy getGroupBy() {
		return this.groupBy;
	}

	public void setOrderBy(OrderBy orderBy) {
		this.orderBy = orderBy;
	}

	public OrderBy getOrderBy() {
		return orderBy;
	}

	public void setLimit(Limit limit) {
		if (limit != null) {
			limit.setParent(this);
		}
		this.limit = limit;
	}

	public Limit getLimit() {
		return limit;
	}

	public void setForUpdate(boolean forUpdate) {
		this.forUpdate = forUpdate;
	}

	public boolean isForUpdate() {
		return forUpdate;
	}

	@Override
	protected void accept0(Visitor visitor) {
		if (visitor.visit(this)) {
			acceptChild(visitor, this.selectItemList);
			acceptChild(visitor, this.from);
			acceptChild(visitor, this.where);
			acceptChild(visitor, this.groupBy);
			acceptChild(visitor, this.orderBy);
			acceptChild(visitor, this.limit);
		}
		visitor.endVisit(this);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (quantifier == null ? 0 : quantifier.hashCode());
		result = prime * result + ((selectItemList == null) ? 0 : selectItemList.hashCode());
		result = prime * result + ((from == null) ? 0 : from.hashCode());
		result = prime * result + ((where == null) ? 0 : where.hashCode());
		result = prime * result + ((groupBy == null) ? 0 : groupBy.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null)
			return false;
		if (getClass() != o.getClass())
			return false;
		Query other = (Query) o;

		if (quantifier != other.quantifier)
			return false;
		if (from == null) {
			if (other.from != null)
				return false;
		} else if (!from.equals(other.from))
			return false;
		if (groupBy == null) {
			if (other.groupBy != null)
				return false;
		} else if (!groupBy.equals(other.groupBy))
			return false;
		if (selectItemList == null) {
			if (other.selectItemList != null)
				return false;
		} else if (!selectItemList.equals(other.selectItemList))
			return false;
		if (where == null) {
			if (other.where != null)
				return false;
		} else if (!where.equals(other.where))
			return false;
		return true;
	}

}
